<template><div><h2 id="引入" tabindex="-1"><a class="header-anchor" href="#引入"><span>引入</span></a></h2>
<p>从浏览器地址栏敲入一个url到我们看到页面之间，浏览器做了什么？</p>
<ol>
<li>从浏览器缓存，电脑本地的host文件，路由器缓存，dns服务器依次查找域名的ip地址，直到找到为止</li>
<li>向这个地址发起http请求，进行TCP连接的三次握手。对于https而言，还需要另一次握手（TLS协商），决定使用哪种密码进行加密。</li>
<li>获取html文件</li>
<li>进行TCP连接的四次挥手</li>
<li>解析html文件</li>
</ol>
<h2 id="浏览器如何解析html文件" tabindex="-1"><a class="header-anchor" href="#浏览器如何解析html文件"><span>浏览器如何解析html文件</span></a></h2>
<p>获取html文件后，将构建dom树作为一个任务放入到宏任务队列中，由浏览器主线程进行执行，并从dom树的html根节点进行子节点递归遍历。遍历到style节点,构建css对象模型，遍历到script标签，内联脚本直接执行，外联脚本会先引入脚本在执行，此时阻塞整个线程，如果是async，derfer属性则将回调函数放入到任务队列中，不会阻塞整个线程。</p>
<p>当dom和cssom解析完成后，会合成并创建一个渲染树，然后计算每个可见元素的布局，通过系统api调用gpu在屏幕上进行绘制。后如果任务队列中还有未执行的任务，则继续执行任务，此时无法触发任何的事件。</p>
<h2 id="浏览器的事件循环机制" tabindex="-1"><a class="header-anchor" href="#浏览器的事件循环机制"><span>浏览器的事件循环机制</span></a></h2>
<p>EventLoop （事件循环），浏览器任务分为宏任务和微任务。
宏任务主要包含：script（整体代码）、setTimeout、setInterval、setImmediate、I/O、UI 交互事件。
微任务主要包括：微任务主要包含：Promise、MutationObserver 等。
当执行完一个宏任务的时候，浏览器主线程就会去查看微任务队列是否存在可以执行的微任务，当所有可以执行的微任务执行完毕后，再去宏任务队列获取新的宏任务，依次往复。</p>
<h2 id="实验" tabindex="-1"><a class="header-anchor" href="#实验"><span>实验</span></a></h2>
<p>微任务队列</p>
<div class="language-html line-numbers-mode has-collapsed-lines collapsed" data-highlighter="shiki" data-ext="html" style="--vp-collapsed-lines:15;background-color:#282c34;color:#abb2bf"><pre class="shiki one-dark-pro vp-code" v-pre=""><code><span class="line"><span style="color:#ABB2BF">&#x3C;!</span><span style="color:#E06C75">DOCTYPE</span><span style="color:#D19A66"> html</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E06C75">html</span><span style="color:#D19A66"> lang</span><span style="color:#ABB2BF">=</span><span style="color:#98C379">"en"</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E06C75">head</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">    &#x3C;</span><span style="color:#E06C75">meta</span><span style="color:#D19A66"> charset</span><span style="color:#ABB2BF">=</span><span style="color:#98C379">"UTF-8"</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">    &#x3C;</span><span style="color:#E06C75">title</span><span style="color:#ABB2BF">>test2&#x3C;/</span><span style="color:#E06C75">title</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;/</span><span style="color:#E06C75">head</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E06C75">body</span><span style="color:#ABB2BF">></span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;</span><span style="color:#E06C75">script</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#E5C07B">    console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">1</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#61AFEF">    setTimeout</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">() {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">        console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">2</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">        new</span><span style="color:#E5C07B"> Promise</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">resolve</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">            console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">3</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#61AFEF">            resolve</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">4</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">        }).</span><span style="color:#61AFEF">then</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">num</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">            console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">num</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">        })</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    }, </span><span style="color:#D19A66">300</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color:#C678DD">    new</span><span style="color:#E5C07B"> Promise</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">resolve</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">        console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">5</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#61AFEF">        resolve</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">6</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    }).</span><span style="color:#61AFEF">then</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75;font-style:italic">num</span><span style="color:#ABB2BF">) {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">        console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#E06C75">num</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    })</span></span>
<span class="line"></span>
<span class="line"><span style="color:#61AFEF">    setTimeout</span><span style="color:#ABB2BF">(</span><span style="color:#C678DD">function</span><span style="color:#ABB2BF">() {</span></span>
<span class="line"></span>
<span class="line"><span style="color:#E5C07B">        console</span><span style="color:#ABB2BF">.</span><span style="color:#61AFEF">log</span><span style="color:#ABB2BF">(</span><span style="color:#D19A66">7</span><span style="color:#ABB2BF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color:#ABB2BF">    }, </span><span style="color:#D19A66">400</span><span style="color:#ABB2BF">)</span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;/</span><span style="color:#E06C75">script</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;/</span><span style="color:#E06C75">body</span><span style="color:#ABB2BF">></span></span>
<span class="line"><span style="color:#ABB2BF">&#x3C;/</span><span style="color:#E06C75">html</span><span style="color:#ABB2BF">></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div><div class="collapsed-lines"></div></div><p>输出结果：1 5 6 2 3 4 7</p>
<blockquote>
<p>执行结果分析：遇到script标签，把整体代码当做一个宏任务放入到宏任务队列中，开始执行代码，先打印1，遇到定时器，把回调函数放入宏任务队列，遇到promise，先打印了5，把回调函数放入到微观队列中，遇到第二个定时器，回调函数放入到宏任务队列，此时第一个宏任务执行完毕。查看微任务队列，执行promise1的回调打印6，无继续可以执行的微任务，查看宏任务队列执行定时器1的回调打印2，将回调放入微任务队列，此时宏任务执行完毕，查看微任务队列，打印4，执行微任务完毕，查看宏任务队列执行定时器2的回调，打印7，此时宏任务，微任务队列都为空，执行完毕，等待新任务。</p>
</blockquote>
<hr>
<blockquote>
<p>引用：<br>
https://developer.mozilla.org/zh-CN/docs/Web/Performance/Guides/How_browsers_work#%E6%A6%82%E8%BF%B0
https://segmentfault.com/a/1190000042909353
https://zhuanlan.zhihu.com/p/445810614
https://cloud.tencent.com/developer/article/2361370
https://juejin.cn/post/7024751918484291591</p>
</blockquote>
</div></template>


